<?php
if (!defined('APP_ID')) { die('No direct script access allowed'); }

/**
 * Hooks class
 */
class Hooks {
	private static $_instance = null;
	private $_container = array();

	public static function &instance() {
		if (!isset(self::$_instance)) {
			$c = __CLASS__;
			self::$_instance = new $c;
		}

		return self::$_instance;
	}

	public function __clone() {
		throw new Node_Exception('Can`t clone singletone object');
	}

	/**
	 * Constructor
	 */
	private function __construct() {
		if (Config::get('enabled', 'hooks')) {
			foreach (Config::get('rules', 'hooks') as $id => $hook) {
				$this->_add($id, $hook);
			}
		}
	}

	/**
	 * Constructor
	 */
	public static function execute($id) {
		if (Config::get('enabled', 'hooks')) {
			$hooks = self::instance();
			if (isset($hooks->_container[$id])) {
				$hook = $hooks->_container[$id];
				foreach ($hook as $hook_item) {
					call_user_func_array(
						array($hook_item['class'], $hook_item['method']),
						$hook_item['params']
					);
				}
			}
		}
	}

	/**
	 * Add hook
	 */
	private function _add($id, $hook) {
		foreach ($hook as $hook_item) {
			if (!isset($hook_item['target'])) {
				$hook_item['target'] = 'both';
			}
			if (($hook_item['target'] == 'web') && Input::isCli()) { continue; }
			if (($hook_item['target'] == 'cli') && !Input::isCli()) { continue; }

			if (!isset($hook_item['params'])) {
				$hook_item['params'] = array();
			}

			$this->_container[$id][] = $hook_item;
		}
	}
}